Skip to content

Allow configuring cascade deletion in DABs#5846

Open
ronaldz-db wants to merge 6 commits into
databricks:mainfrom
ronaldz-db:pipelines-destroy-cascade
Open

Allow configuring cascade deletion in DABs#5846
ronaldz-db wants to merge 6 commits into
databricks:mainfrom
ronaldz-db:pipelines-destroy-cascade

Conversation

@ronaldz-db

@ronaldz-db ronaldz-db commented Jul 8, 2026

Copy link
Copy Markdown

Changes

Add a cascade_on_destory field to the pipeline bundle resource that controls whether destroying a pipeline also cascades to its datasets. When unset, we maintain the existing default of true.

This change applies to the direct engine. We have a separate change on the Terraform side: databricks/terraform-provider-databricks#5860

Why

Previously, pipeline deletion would automatically cascade to its tables. After user feedback, we decided to make this configurable in the DeletePipeline API. This extends support to DABs as well, which was another common user ask.

Tests

Unit tests

Add a `cascade` field to the pipeline bundle resource that controls whether
destroying a pipeline also deletes its datasets (materialized views, streaming
tables, and views). When unset, the server default applies (cascade); set
`cascade: false` to retain the datasets on destroy.

The field is delete-time only: it is not part of the pipeline spec, so it is
never sent on create/update. The direct engine persists it in state (via a
PipelineState wrapper around CreatePipeline, mirroring the sql_warehouse
lifecycle pattern) and reads it at delete time, force-sending cascade so an
explicit false survives query-string omitempty (honored for query params as of
databricks-sdk-go v0.152.0). A cascade-only change is a state-only update with
no pipeline API call. cascade is classified input_only so it does not show
remote drift.

The terraform engine drops the field for now: the pinned provider has no such
attribute yet (pending terraform-provider-databricks#5860), so terraform-engine
support is a follow-up.

Co-authored-by: Isaac
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Approval status: pending

/acceptance/bundle/ - needs approval

29 files changed
Suggested: @pietern
Also eligible: @denik, @janniklasrose, @andrewnester, @shreyas-goenka, @lennartkats-db, @anton-107

/acceptance/pipelines/ - needs approval

14 files changed
Suggested: @lennartkats-db
Also eligible: @kanterov, @jefferycheng1

/bundle/ - needs approval

12 files changed
Suggested: @pietern
Also eligible: @denik, @janniklasrose, @andrewnester, @shreyas-goenka, @lennartkats-db, @anton-107

General files (require maintainer)

Files: .nextchanges/bundles/cascade-on-destroy.md
Based on git history:

  • @pietern -- recent work in bundle/config/mutator/, bundle/schema/, bundle/phases/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db, @janniklasrose, @lennartkats-db) can approve all areas.
See OWNERS for ownership rules.

Comment thread bundle/direct/dresources/pipeline.go
Comment thread acceptance/pipelines/destroy/destroy-pipeline-cascade/databricks.yml Outdated
Comment thread acceptance/pipelines/destroy/destroy-pipeline-cascade/output.txt
pipelines:
my_pipeline:
name: test-pipeline-cascade
cascade: false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you make sure the default template also sets purge_on_destroy: false? With a very short comment to the side explaining it? Could be a separate PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack will put this change in a follow-up PR.

Comment thread acceptance/pipelines/destroy/destroy-pipeline-cascade/test.toml Outdated
… message fix

- Rename the pipeline config field cascade -> cascade_on_destroy, matching the
  Lakebase purge_on_delete precedent (per review discussion).
- Add ValidateCascadeOnDestroy mutator: hard error when the field is used with
  the terraform engine, which does not support it yet.
- Fix the destroy approval message so a pipeline with cascade_on_destroy: false
  is not described as deleting its STs/MVs, and mention the property otherwise.
- Comment why ForceSendFields is needed in DoDelete.
- Regenerate schema, refschema, and affected acceptance outputs.

Co-authored-by: Isaac
Comment thread acceptance/pipelines/destroy/destroy-pipeline-cascade/output.txt
Comment thread bundle/phases/destroy.go
Comment thread acceptance/pipelines/destroy/destroy-pipeline-cascade/databricks.yml Outdated
pipelines:
my_pipeline:
name: test-pipeline-cascade
cascade: false

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack will put this change in a follow-up PR.

ronaldz-db added a commit to ronaldz-db/terraform-provider-databricks that referenced this pull request Jul 15, 2026
Align the pipeline destroy-time attribute name with the DABs config field
(databricks/cli#5846), which settled on cascade_on_destroy.

Co-authored-by: Isaac
Comment thread .vscode/settings.json Outdated
Comment thread bundle/config/resources/pipeline.go

This action will result in the deletion of the following Lakeflow Spark Declarative Pipelines along with the
Streaming Tables (STs) and Materialized Views (MVs) managed by them:
Streaming Tables (STs) and Materialized Views (MVs) managed by them. Set 'cascade_on_destroy: false' on a pipeline to retain datasets on pipeline deletion:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Streaming Tables (STs) and Materialized Views (MVs) managed by them. Set 'cascade_on_destroy: false' on a pipeline to retain datasets on pipeline deletion:
Streaming Tables (STs) and Materialized Views (MVs) managed by them. Set 'cascade_on_destroy: false' on a pipeline to retain the Streaming Tables and Materialized Views on pipeline deletion:

datasets seems like a vague term to use here? In the context of dashboards, for example, this just means a SQL query.

I could be wrong about this, so if this is standard for pipelines, feel free to keep it as is.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We generally use datasets in pipelines docs now, since pipeline-owned tables have been changing recently. Now, we also allow users to create Views in pipelines. In the near future, we plan to switch to creating regular delta tables as well.

Comment thread bundle/direct/dresources/pipeline.go Outdated
type PipelineRemote struct {
pipelines.CreatePipeline

CascadeOnDestroy *bool `json:"cascade_on_destroy,omitempty"`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be omitted from this struct because cascade on destroy will never be set in the remote. It'll never be returned as part of the get response

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I was confused and thought that there was a strict requirement that PipelineRemote be a superset. But looking closer, I don't think there a benefit to defining for the remote version. Dropped it

Comment thread bundle/direct/dresources/pipeline.go
Comment thread bundle/direct/dresources/pipeline.go Outdated
Comment thread bundle/phases/messages.go
deletePipelineWithCascadeMessage = `This action will result in the deletion of the following Lakeflow Spark Declarative Pipelines along with the
Streaming Tables (STs) and Materialized Views (MVs) managed by them. Set 'cascade_on_destroy: false' on a pipeline to retain datasets on pipeline deletion:`

deletePipelineNoCascadeMessage = `This action will result in the deletion of the following Lakeflow Spark Declarative Pipelines.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

Comment thread bundle/phases/plan.go Outdated
Drop the files.watcherExclude block that was unrelated to the
cascade_on_destroy feature, per review feedback.

Co-authored-by: Isaac
- Add docs URL to the terraform-engine validation error so users can
  learn about direct deployment mode.
- Omit CascadeOnDestroy from PipelineRemote: it is an input-only,
  delete-time setting the GET response never returns, so drift is
  suppressed automatically (missing_in_remote). Matches the postgres
  input-only field pattern.
- Propagate errors from pipelineDeletionCascades instead of silently
  defaulting, and add unit coverage.

Co-authored-by: Isaac
@github-actions

Copy link
Copy Markdown
Contributor

An authorized user can trigger integration tests manually by following the instructions below:

Trigger:
go/deco-tests-run/cli

Inputs:

  • PR number: 5846
  • Commit SHA: 423ca32b692ba3efd28bc2b884659db8add2f764

Checks will be approved automatically on success.

Comment thread bundle/phases/plan.go

v, err := dyn.GetByPath(b.Config.Value(), path)
if err != nil {
return true, nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This embeds a client side default here. Treating unset as true. Won't this get out of date once the server side default changes?

@shreyas-goenka shreyas-goenka Jul 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess there's no good way to handle this scenario? It does mean we'll eventually end up showing wrong messages to people.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a to-do message here to change the value once the server side default flips?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, added a note here. Unfortunately, there may be a brief period where the DABs default and server-side default are different. But the DABs documentation describes the actual encoded behavior, so we won't be showing the wrong messages

Comment thread bundle/phases/plan.go

v, err := dyn.GetByPath(b.Config.Value(), path)
if err != nil {
return true, nil

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a to-do message here to change the value once the server side default flips?

Comment thread bundle/phases/messages.go
deletePipelineWithCascadeMessage = `This action will result in the deletion of the following Lakeflow Spark Declarative Pipelines along with the
Streaming Tables (STs) and Materialized Views (MVs) managed by them. Set 'cascade_on_destroy: false' on a pipeline to retain datasets on pipeline deletion:`

deletePipelineNoCascadeMessage = `This action will result in the deletion of the following Lakeflow Spark Declarative Pipelines.

@shreyas-goenka shreyas-goenka Jul 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GPT 5.6 flagged a crucial bug. @ronaldz-db we need to read the cascade_on_delete value from state when showing the prompt. Otherwise we risk deleting a user's table when tell them that we'll not:

Critical — approval can falsely promise dataset retention. /tmp/isaac-review-cli/bundle/phases/plan.go:46 reads the current YAML, while deletion uses persisted state.
    If a user changes cascade_on_destroy to false and immediately destroys without deploying, the prompt says datasets are retained, but the API uses the old state and
    cascades. Derive both behavior and messaging from the same state; add regression coverage for this sequence.

  Focused package tests pass. Current CI failures are unrelated JFrog OIDC setup failures.

  REQUEST CHANGES

@shreyas-goenka shreyas-goenka Jul 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check if this feedback is valid? I suspect it is because from I recall we indeed only rely on the state for delete / destroy operations.

Please also add an acceptance test to ensure that we do the right thing when a user sets this field but then immediately destroys the bundle the bundle without a deployment.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh shoot, thanks for the catch. This feedback is valid. I've updated the message to be generated by reading the state value for the direct engine and added a test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable cascade delete feature on pipeline for databricks deploy

3 participants